package com.ustc.hewei.rpc.client.loadbalance.impl;

import com.ustc.hewei.rpc.client.loadbalance.LoadBalanceChoose;
import com.ustc.hewei.rpc.common.protocol.Service;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

/**
* @description: 一致性哈希负载均衡
* @author hewei
* @date 2022/8/19 10:01
* @version 1.0
*/

public class ConsistentHash implements LoadBalanceChoose {

    @Override
    public Service chooseService(String serviceName, List<Service> services) {
        try {
            //一致性哈希实现
            String clientIp;
            clientIp = InetAddress.getLocalHost().getHostAddress();
            int code = clientIp.hashCode();
            //需要进行与的操作，因为得到的哈希值有可能是负数，取余后还是负数，下标越界
            //为什么哈希值会变成负的呢，因为当哈希值超过正整数的范围时，就会将符号位置为1，导致为负
            return services.get((code & Integer.MAX_VALUE) % services.size());
        } catch (UnknownHostException e) {
            e.printStackTrace();
            throw new RuntimeException("获取客户端ip异常", e);
        }
    }

    @Override
    public Service nextService(List<Service> services, String serviceName, int offset) {
        try {
            String clientIp = InetAddress.getLocalHost().getHostAddress();
            int code = clientIp.hashCode();
            int index = (code & Integer.MAX_VALUE) % services.size() + offset;
            return services.get(index % services.size());
        } catch (UnknownHostException e) {
            throw new RuntimeException("获取下一个服务失败！", e);
        }
    }
}
